package com.example.pvj.toucheventdemo;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.components.Text;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;

import com.example.pvj.toucheventdemo.bean.MusicData;

import java.util.ArrayList;
import java.util.List;

/**
 * DragLayout
 *
 * @since 2021-11-11
 */
public class DragLayout extends DependentLayout {
    private HiLogLabel logLabel = new HiLogLabel(HiLog.LOG_APP, 0x222, "DragLayout");

    private int H = 1600;
    private float dragStartPointY;
    private int marginBottom;

    public DragLayout(Context context) {
        this(context, null);
    }

    public DragLayout(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public DragLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init();
    }

    DirectionalLayout directionalLayout;
    Component bgComponent;
    ListContainer listContainer;

    Text titleText;
    Text subText;
    Image img;

    private void init() {

        Component topComponent = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_layout_top, this, true);
        titleText = topComponent.findComponentById(ResourceTable.Id_title);
        subText = topComponent.findComponentById(ResourceTable.Id_tv_sub);
        img = topComponent.findComponentById(ResourceTable.Id_img);

        bgComponent = new Component(getContext());
        ShapeElement bgElement = new ShapeElement();
        bgElement.setRgbColor(RgbColor.fromArgbInt(0xff000000));
        bgComponent.setBackground(bgElement);
        addComponent(bgComponent, ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);
        bgComponent.setAlpha(0.0f);

        directionalLayout = new DirectionalLayout(getContext());
        directionalLayout.setOrientation(Component.VERTICAL);
        addBar();

        listContainer = new ListContainer(getContext());
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(0xffffffff));
        listContainer.setBackground(shapeElement);

        setNewsListData(getData(), listContainer);
        directionalLayout.addComponent(listContainer, ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT);


        listContainer.setTouchEventListener(new TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                marginBottom = directionalLayout.getMarginBottom();
                boolean drag_down = listContainer.canScroll(DRAG_DOWN);
                boolean drag_UP = listContainer.canScroll(DRAG_UP);
                if (marginBottom == 0 && drag_down) {
                    component.setEnabled(true);
                    return true;
                }
                component.setEnabled(false);
                return false;
            }
        });


        setTouchEventListener(new TouchEventListener() {
            @Override
            public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
                HiLog.info(logLabel, "onTouchEvent action:" + touchEvent.getAction());
                switch (touchEvent.getAction()) {
                    case TouchEvent.PRIMARY_POINT_DOWN:
                        marginBottom = directionalLayout.getMarginBottom();
                        MmiPoint position = touchEvent.getPointerScreenPosition(0);
                        if (isTouchPointInComponent(directionalLayout, position.getX(), position.getY())) {
                            dragStartPointY = touchEvent.getPointerPosition(0).getY();
                            return true;
                        }
                        break;
                    case TouchEvent.PRIMARY_POINT_UP:
                        onTouchUp();
                        break;
                    case TouchEvent.POINT_MOVE:
                        float y = touchEvent.getPointerPosition(0).getY();
                        float offY = dragStartPointY - y;
                        setDrawerMarginBottom((int) offY);
                        break;
                }
                return false;
            }
        });
    }

    private void onTouchUp() {
        HiLog.info(logLabel, "onTouchUp");
        createAnimator();
    }


    private void createAnimator() {
        marginBottom = directionalLayout.getMarginBottom();
        HiLog.info(logLabel, "createAnimator marginBottom:" + marginBottom);
        //创建数值动画对象
        AnimatorValue animatorValue = new AnimatorValue();
        //动画时长
        animatorValue.setDuration(300);
        //播放前的延迟时间
        animatorValue.setDelay(0);
        //循环次数
        animatorValue.setLoopedCount(0);
        //动画的播放类型
        animatorValue.setCurveType(Animator.CurveType.ACCELERATE_DECELERATE);
        //设置动画过程
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                HiLog.info(logLabel, "createAnimator value:" + value);
                if (marginBottom > -H / 4) { // top
                    HiLog.info(logLabel, "createAnimator top:" + value);
                    setDrawerBottomOrToP((int) (marginBottom - value * marginBottom));
                } else { // bottom
                    HiLog.info(logLabel, "createAnimator bottom:" + value);
                    int top = H / 2 + marginBottom;
                    setDrawerBottomOrToP((int) (marginBottom - value *top));
                }
            }
        });
        //开始启动动画
        animatorValue.start();
    }


    private void setDrawerBottomOrToP(int bottom) {
        if (bottom > 0) {
            bottom = 0;
            listContainer.setEnabled(true);
        }

        if (bottom < -H / 2) {
            bottom = -H / 2;
        }
        HiLog.info(logLabel, "setDrawerBottomOrToP bottom:" + bottom);

        float alpha = (0.5f - Math.abs((float) bottom / (float) H)) * 0.5f;
        HiLog.info(logLabel, "setDrawerBottomOrToP alpha:" + alpha);
        bgComponent.setAlpha(alpha);
        directionalLayout.setMarginBottom(bottom);
    }

    private void addBar() {
        LayoutConfig layoutConfig = new LayoutConfig();
        layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
        layoutConfig.height = H;
        layoutConfig.setMarginBottom(-H / 2);
        layoutConfig.addRule(LayoutConfig.ALIGN_PARENT_BOTTOM);
        addComponent(directionalLayout, layoutConfig);

        DependentLayout barLayout = new DependentLayout(getContext());
        Element barBgElement = new ShapeElement(getContext(), ResourceTable.Graphic_background_bar1);
        barLayout.setBackground(barBgElement);
        directionalLayout.addComponent(barLayout, ComponentContainer.LayoutConfig.MATCH_PARENT, 100);

        Component component = new Component(getContext());
        Element barBgElement1 = new ShapeElement(getContext(), ResourceTable.Graphic_background_bar);
        component.setBackground(barBgElement1);
        LayoutConfig layoutConfig3 = new LayoutConfig();
        layoutConfig3.width = ComponentContainer.LayoutConfig.MATCH_PARENT;
        layoutConfig3.height = 100;
        layoutConfig3.setMarginTop(2);
        barLayout.addComponent(component, layoutConfig3);


        Image image = new Image(getContext());
        Element element = new ShapeElement(getContext(), ResourceTable.Graphic_bar);
        image.setImageElement(element);
        LayoutConfig layoutConfig2 = new LayoutConfig();
        layoutConfig2.addRule(LayoutConfig.CENTER_IN_PARENT);
        layoutConfig2.width = 100;
        layoutConfig2.height = 15;
        barLayout.addComponent(image, layoutConfig2);
    }


    int num = 25;
    String[] titles = new String[]{
        "大风吹", "相见恨晚", "你笑起来真好看", "别人口中陌生的我", "踏山河（女生版）（cover：是七叔呀）"
    };
    String[] singers = new String[]{
        "王X野", "彭佳慧", "李佳莹", "鱼妹Miya", "张小菲"
    };
    String[] subNames = new String[]{
        "大风吹", "彭游恋歌最爱精选", "你笑起来真好看", "别人口中陌生的我", "单曲发型"
    };

    int[] imgRids = new int[]{
        ResourceTable.Media_p1, ResourceTable.Media_p2, ResourceTable.Media_p3,
        ResourceTable.Media_p4, ResourceTable.Media_p5
    };

    private List<MusicData> getData() {
        List<MusicData> datas = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            MusicData data = new MusicData();
            data.index = i + 1;
            data.title = titles[i];
            data.singer = singers[i];
            data.subName = subNames[i];
            data.imgRid = imgRids[i];
            datas.add(data);
        }

        for (int i = 0; i < num; i++) {
            MusicData data = new MusicData();
            data.index = i + 6;
            data.title = "歌曲xxx" + i;
            data.singer = "歌手YYY" + i;
            data.subName = "专辑ZZZ" + i;
            data.imgRid = ResourceTable.Media_p6;
            datas.add(data);
        }
        return datas;
    }

    List<MusicData> data;

    private void setNewsListData(List<MusicData> data, ListContainer listContainer) {
        this.data = data;
        MusicListProvider mProvider = new MusicListProvider(data, getContext());
        listContainer.setItemProvider(mProvider);
        listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
            @Override
            public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                HiLog.info(logLabel, "onItemClicked i:" + i);
                setUI(i);
                mProvider.setCurSelectPosition(i);
            }
        });
        setUI(0);
    }

    private void setUI(int index) {
        MusicData musicData = data.get(index);
        titleText.setText(musicData.title);
        subText.setText(musicData.singer + "-" + musicData.subName);
        img.setPixelMap(musicData.imgRid);
    }

    private void setDrawerMarginBottom(int offY) {
        int bottom = marginBottom + offY;
        if (bottom > 0) {
            bottom = 0;
            listContainer.setEnabled(true);
        }

        if (bottom < -H / 2) {
            bottom = -H / 2;
        }
        HiLog.info(logLabel, "setDrawerMarginBottom bottom:" + bottom);

        float alpha = (0.5f - Math.abs((float) bottom / (float) H)) * 0.5f;
        HiLog.info(logLabel, "setDrawerMarginBottom alpha:" + alpha);
        bgComponent.setAlpha(alpha);
        directionalLayout.setMarginBottom(bottom);
    }

    /**
     * (x,y)是否在view的区域内
     *
     * @param component
     * @param x
     * @param y
     * @return
     */
    private boolean isTouchPointInComponent(Component component, float x, float y) {
        int[] locationOnScreen = component.getLocationOnScreen();
        int left = locationOnScreen[0];
        int top = locationOnScreen[1];
        int right = left + component.getEstimatedWidth();
        int bottom = top + component.getEstimatedHeight();
        boolean inY = y >= top && y <= bottom;
        boolean inX = x >= left && x <= right;
        return inY && inX;
    }

}
